/// ===========================================================================
/// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
/// KIND, WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
/// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
/// PURPOSE.
/// ===========================================================================
/// 
/// Project:        MOSS Faceted Search
/// Author:         Leonid Lyublinski (leonidly@microsoft.com)
/// Company:        Microsoft Services
/// Date:           05/04/2007      Version:        1.0 
///
/// ===========================================================================

using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using System.Xml.Serialization;
using System.Data;
using Microsoft.SharePoint.WebPartPages;
using Microsoft.Office.Server;
using Microsoft.Office.Server.Search.Query;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;

namespace Microsoft.SharePoint.Portal.ExtendedSearch.WebControls
{

    /// <summary>
    /// Class defines templates used for facet data binding
    /// </summary>
    public class FacetTemplate : Control, INamingContainer, ITemplate
    {
        private ListItemType _type;
        private string _cssClass;
        private short _cropMax = 20;

        public FacetTemplate(ListItemType type, string cssClass)
        {
            _type = type;
            _cssClass = cssClass;
        }

        public FacetTemplate(ListItemType type, string cssClass, short cropMax)
        {
            _type = type;
            _cssClass = cssClass;
            _cropMax = cropMax;
        }

        #region ITemplate Members
        public void InstantiateIn(Control container)
        {
            LinkButton link = new LinkButton();
            link.CssClass = _cssClass;
            Label hits = new Label();
            //hits.CssClass = _cssClass;

            switch (_type)
            {
                case ListItemType.Header:
                    break;
                case ListItemType.Item:
                    link.DataBinding += new EventHandler(link_DataBinding);
                    //container.Controls.Add(new LiteralControl("<li>"));
                    container.Controls.Add(new LiteralControl(@"
                        <table border=""0"" cellpadding=""0"" cellspacing=""0"" class=""" + _cssClass + @""" width=""100%"">
                            <tr>
                                <td nowrap=""nowrap"" width=""100%"">"));
                    container.Controls.Add(link);
                    container.Controls.Add(hits);
                    container.Controls.Add(new LiteralControl(@"</td></tr></table>"));

                    hits.DataBinding += new EventHandler(hits_DataBinding);
                    //container.Controls.Add(new LiteralControl("</li>"));
                    break;
                case ListItemType.AlternatingItem:
                    break;
                case ListItemType.Footer:
                    break;
            }
        }

        void hits_DataBinding(object sender, EventArgs e)
        {
            Label hits = (Label)sender;
            IDataItemContainer container = (IDataItemContainer)hits.NamingContainer;
            Facet facet = (Facet)container.DataItem;
            hits.Text = " (" + facet.Hits.ToString() + ")";
        }

        void link_DataBinding(object sender, EventArgs e)
        {
            LinkButton link = (LinkButton)sender;
            IDataItemContainer container = (IDataItemContainer)link.NamingContainer;
            Facet facet = (Facet)container.DataItem;

            string propValue = facet.Name;
            if (propValue.Length > _cropMax)
            {
                link.ToolTip = propValue;
                link.Text = propValue.Remove(_cropMax) + "...";
            }
            else link.Text = propValue;
            link.CommandName = "SelectFacet";
            link.CommandArgument = facet.Hits.ToString();
        }
        #endregion
    }


    /// <summary>
    /// Class defines templates used for bread crumb data binding
    /// </summary>
    public class CrumbTemplate : Control, INamingContainer, ITemplate
    {
        private ListItemType _type;
        private string _cssClass;
        private string _qs;
        private string _path;

        public CrumbTemplate(ListItemType type, string cssClass)
        {
            _type = type;
            _cssClass = cssClass;
            _qs = HttpUtility.UrlDecode(HttpContext.Current.Request.QueryString.ToString());
            _path = HttpContext.Current.Request.Url.AbsolutePath;
        }

        #region ITemplate Members
        public void InstantiateIn(Control container)
        {
            HyperLink link = new HyperLink();
            //link.CssClass = _cssClass;
            link.Text = "x";
            link.EnableViewState = false;
            Label facet = new Label();
            facet.EnableViewState = false;
            //facet.CssClass = _cssClass;
            switch (_type)
            {
                case ListItemType.Header:
                    break;
                case ListItemType.Item:
                    link.DataBinding += new EventHandler(link_DataBinding);
                    facet.DataBinding += new EventHandler(facet_DataBinding);
                    container.Controls.Add(new LiteralControl(string.Format(@"<SPAN class=""{0}"">", _cssClass)));
                    container.Controls.Add(facet);
                    container.Controls.Add(new LiteralControl(@"<SUP>("));
                    container.Controls.Add(link);
                    container.Controls.Add(new LiteralControl(@")</SUP></SPAN>"));

                    break;
                case ListItemType.AlternatingItem:
                    break;
                case ListItemType.Footer:
                    break;
            }
        }

        void facet_DataBinding(object sender, EventArgs e)
        {
            Label facet = (Label)sender;
            IDataItemContainer container = (IDataItemContainer)facet.NamingContainer;
            DictionaryEntry entry = (DictionaryEntry)container.DataItem;
            string key = entry.Key.ToString();
            string value = entry.Value.ToString();
            facet.Text = string.Format("{0}:{1}", key, value);
        }

        void link_DataBinding(object sender, EventArgs e)
        {
            HyperLink link = (HyperLink)sender;
            IDataItemContainer container = (IDataItemContainer)link.NamingContainer;
            DictionaryEntry entry = (DictionaryEntry)container.DataItem;
            string key = entry.Key.ToString();
            string value = entry.Value.ToString();
            link.NavigateUrl = GetUrl(key, value);
        }

        private string GetUrl(string facetName, string facetValue) {
            string url = _path;
            string pattern = facetName + ":\"" + facetValue + "\"";
            Regex re = new Regex(pattern);
            url += "?" + re.Replace(_qs, "");
            return url.Replace("  ", " ");
        }
        #endregion
    }

    /// <summary>
    /// Class defines templates used for bread crumb separation
    /// </summary>
    public class SeparatorTemplate : Control, INamingContainer, ITemplate
    {
        private ListItemType _type;
        private string _separator;
        private string _cssClass;

        public SeparatorTemplate(ListItemType type, string cssClass, string separator)
        {
            _type = type;
            _cssClass = cssClass;
            _separator = separator;
        }

        #region ITemplate Members
        public void InstantiateIn(Control container)
        {
            Label sep = new Label();
            sep.EnableViewState = false;
            sep.Text = _separator;
            sep.CssClass = _cssClass;
            switch (_type)
            {
                case ListItemType.Header:
                    break;
                case ListItemType.Separator:
                    container.Controls.Add(sep);
                    break;
                case ListItemType.AlternatingItem:
                    break;
                case ListItemType.Footer:
                    break;
            }
        }
        #endregion
    }

    /// <summary>
    /// Class defines templates used for bread crumb header
    /// </summary>
    public class HeaderTemplate : Control, INamingContainer, ITemplate
    {
        private ListItemType _type;
        private string _cssClass;
        private string _header;
        private string _toolTip;
        private int _totalResults;


        public HeaderTemplate(ListItemType type, string cssClass, string header, string toolTip, int totalResults)
        {
            _type = type;
            _cssClass = cssClass;
            _header = header;
            _toolTip = toolTip;
            _totalResults = totalResults;

        }

        #region ITemplate Members
        public void InstantiateIn(Control container)
        {
            HyperLink header = new HyperLink();
            header.EnableViewState = false;
            header.Text = _header;
            //header.ToolTip = _toolTip;
            header.CssClass = _cssClass;

            Image icon = new Image();
            icon.ImageUrl = "/_layouts/images/DeployReportInfo.gif";
            icon.ToolTip = _toolTip;

            HyperLink scroll = new HyperLink();
            scroll.ImageUrl = "/_layouts/images/DLMAX.gif";
            scroll.NavigateUrl = "#";
            scroll.Attributes.Add("facet", _header);
            scroll.Text = "collapse/expand facets";
            scroll.Attributes.Add("onclick", "switchFooter(this, '" + _header + "', " + _totalResults + "); return false;");
            
            switch (_type)
            {
                case ListItemType.Header:
                    container.Controls.Add(new LiteralControl(@"
                        <table border=""0"" cellpadding=""0"" cellspacing=""0"" class=""" + _cssClass + @""" width=""100%"">
                            <tr valign=""middle"">
                                <td width=""100%"">"));
                    container.Controls.Add(header);
                    if (_totalResults > 1)
                    {
                        container.Controls.Add(new LiteralControl(@"</td><td>"));
                        container.Controls.Add(scroll);
                    }
                    container.Controls.Add(new LiteralControl(@"</td><td>"));
                    container.Controls.Add(icon);
                    container.Controls.Add(new LiteralControl(@"</td></tr></table>"));
                    break;
                case ListItemType.Separator:
                    break;
                case ListItemType.AlternatingItem:
                    break;
                case ListItemType.Footer:
                    break;
            }
        }
        #endregion
    }

    /// <summary>
    /// Class defines templates used for bread crumb header
    /// </summary>
    public class FooterTemplate : Control, INamingContainer, ITemplate
    {
        private ListItemType _type;
        private string _cssClass;
        private string _footer;
        private int _totalResults;

        public FooterTemplate(ListItemType type, string cssClass, string footer, int totalResults)
        {
            _type = type;
            _cssClass = cssClass;
            _footer = footer;
            _totalResults = totalResults;
        }

        #region ITemplate Members
        public void InstantiateIn(Control container)
        {        
            Label more = new Label();
            more.EnableViewState = false;
            more.Text = "...";
            
            switch (_type)
            {
                case ListItemType.Footer:
                    container.Controls.Add(new LiteralControl(@"
                        <table border=""0"" cellpadding=""0"" cellspacing=""0"" class=""" + _cssClass + @""" width=""100%"">
                            <tr>
                                <td width=""100%"">...</td></tr></table>"));
                    break;
                case ListItemType.Separator:
                    break;
                case ListItemType.AlternatingItem:
                    break;
                case ListItemType.Header:
                    break;
            }
        }
        #endregion
    }
}
